package org.budo.beetl.resource.http;

import org.beetl.core.GroupTemplate;
import org.beetl.core.Resource;
import org.beetl.core.ResourceLoader;
import org.beetl.core.misc.BeetlUtil;
import org.budo.ehcache.config.annotation.EhCacheConfig;
import org.budo.support.http.client.Request;
import org.budo.support.http.client.Response;
import org.budo.support.lang.util.NumberUtil;
import org.budo.support.lang.util.StringUtil;
import org.budo.support.spring.util.SpringUtil;
import org.springframework.cache.annotation.Cacheable;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author limingwei
 */
@Getter
@Setter
@Slf4j
public class BudoHttpBeetlResourceLoader implements ResourceLoader, BudoBeetlHttpResourceClient {
    private String url;

    private String pathToUrl(String path) {
        String url = path;
        while (true) {
            int a = url.indexOf("/../");
            if (a < 0) {
                break;
            }

            int b = url.lastIndexOf("/", a - 1);
            url = url.substring(0, b + 1) + url.substring(a + 4);
        }
        return url;
    }

    @EhCacheConfig(timeToLiveSeconds = 10 * 60, timeToIdleSeconds = 3 * 60, maxElementsInMemory = 40, maxElementsOnDisk = 200)
    @Cacheable(value = "_BudoBeetlHttpResourceClientRequest", unless = "false")
    public String request(String path) {
        String url = this.pathToUrl(path);

        log.info("#44 request, url=" + url + ", this=" + this);

        Request request = new Request();
        request.setUrl(url);
        request.setConnectTimeout(9 * 1000);
        request.setReadTimeout(9 * 1000);
        Response response = request.execute();

        if (NumberUtil.equals(404, response.getStatus()) || NumberUtil.equals(403, response.getStatus())) {
            log.error("#31 response=" + response);
            return STATUS_404;
        }

        if (!NumberUtil.equals(200, response.getStatus())) {
            throw new RuntimeException("#36 response=" + response);
        }

        return response.getBody();
    }

    @Override
    public boolean exist(String id) {
        String path = this.getUrl() + id;
        String body = SpringUtil.getBean(BudoBeetlHttpResourceClient.class).request(path);
        return !StringUtil.equals(STATUS_404, body);
    }

    @Override
    public boolean isModified(Resource resource) {
        return resource.isModified();
    }

    @Override
    public String getResourceId(Resource resource, String id) {
        if (null == resource) {
            return id;
        }

        String relPath = BeetlUtil.getRelPath(resource.getId(), id);
        return relPath;
    }

    @Override
    public Resource getResource(String id) {
        return new BudoHttpBeetlResource(id, this);
    }

    @Override
    public void close() {
        log.info("#55 close, this=" + this);
    }

    @Override
    public void init(GroupTemplate groupTemplate) {
        log.info("#60 init, this=" + this + ", groupTemplate=" + groupTemplate);
    }

    @Override
    public String getInfo() {
        return "this:" + this + ", url:" + this.getUrl();
    }
}